package com.ktjy.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ktjy.base.Q;
import com.ktjy.base.R;
import com.ktjy.service.IService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * API公共基础接口（实现基本增删改查业务接口，提供给业务接口继承）
 *
 * @author LILIBO
 * @since 2021-06-24
 */
public class APIController<Service extends IService<T>, T> {

    /**
     * 业务逻辑基类
     */
    @Autowired // 按类型自动注入依赖
    protected Service baseService;

    /**
     * 新增记录
     *
     * @param entity 实体
     * @return R 成功返回true
     */
    @Operation(summary = "新增记录")
    @PostMapping("/add")
    public R add(@Parameter(description = "实体对象") @RequestBody T entity) {
        return R.success(baseService.save(entity));
    }

    /**
     * 保存或更新记录
     *
     * @param entity 实体（带主键ID表示更新，否则为新增）
     * @return R 成功返回保存后的完整对象
     */
    @Operation(summary = "保存或更新记录")
    @PostMapping("/save")
    public R save(@Parameter(description = "实体对象") @RequestBody T entity) {
        return baseService.saveOrUpdate(entity) ? R.success(entity) : R.failure();
    }

    /**
     * 修改记录
     *
     * @param entity 实体
     * @return R 成功返回true
     */
    @Operation(summary = "修改记录")
    @PostMapping("/update")
    public R update(@Parameter(description = "实体对象") @RequestBody T entity) {
        return R.success(baseService.updateById(entity));
    }

    /**
     * 通过ID删除一条实体记录
     *
     * @param id ID
     * @return R 成功返回true
     */
    @Operation(summary = "通过ID删除一条记录")
    @PostMapping("/delete")
    public R deleteById(@Parameter(description = "实体主键ID") Long id) {
        return R.success(baseService.removeById(id));
    }

    /**
     * 通过多个ID批量删除记录
     *
     * @param ids ID列表
     * @return R 成功返回true
     */
    @Operation(summary = "通过多个ID批量删除记录")
    @PostMapping("/remove")
    public R removeByIds(@Parameter(description = "主键ID列表") @RequestBody List<Long> ids) {
        return R.success(baseService.removeByIds(ids));
    }

    /**
     * 通过ID查询单条记录
     *
     * @param id ID
     * @return R 记录
     */
    @Operation(summary = "通过ID查询单条记录")
    @GetMapping("/{id}")
    public R getById(@Parameter(description = "实体主键ID") @PathVariable Long id) {
        return R.success(baseService.getById(id));
    }

    /**
     * 获取数量
     *
     * @param entity 查询的特征对象
     * @return R 符合条件的数据量
     */
    @Operation(summary = "获取数量")
    @GetMapping("/count")
    public R count(@Parameter(description = "查询的特征对象") T entity) {
        return R.success(baseService.count(entity));
    }

    /**
     * 查询列表
     *
     * @param entity 查询的特征对象
     * @return R 列表
     */
    @Operation(summary = "查询列表")
    @GetMapping("/list")
    public R list(@Parameter(description = "查询的特征对象") T entity) {
        return R.success(baseService.list(entity));
    }

    /**
     * 分页查询
     *
     * @param pageNo 当前页
     * @param pageSize 每页条数
     * @param entity 查询的特征对象
     * @return
     */
    @Operation(summary = "分页查询")
    @GetMapping("/page")
    public R page(@Parameter(description = "当前页") @RequestParam(required = false, defaultValue = "1") Long pageNo, @Parameter(description = "每页条数") @RequestParam(required = false, defaultValue = "10") Long pageSize, @Parameter(description = "查询的特征对象") T entity) {
        return R.success(baseService.page(new Page<>(pageNo, pageSize), entity));
    }

    /**
     * 分页查询列表
     *
     * @param pageNo 当前页
     * @param pageSize 每页条数
     * @param param 通用查询参数
     * @return 返回分页数据列表，其中count为数据总量
     */
    @Operation(summary = "分页查询列表")
    @GetMapping("/querypage")
    public R queryPage(@Parameter(description = "当前页") @RequestParam(required = false, defaultValue = "1") Long pageNo, @Parameter(description = "每页条数") @RequestParam(required = false, defaultValue = "10") Long pageSize, @Parameter(description = "通用查询参数") Q param) {
        IPage<T> page = baseService.queryPage(new Page<>(pageNo, pageSize), param);
        return R.success(page.getTotal(), page.getRecords());
    }

}
